use rsdp::*;

fn main() {
    命令行运行();
}

fn 命令行运行() {
    let 选项一 = 获取选项一();
    match 选项一.as_str() {
        "1" => {
            let 选项二 = 获取选项二("创建型模式");
            match 选项二.as_str() {
                "1" => 工厂方法::main(),
                "2" => 抽象工厂::main(),
                "3" => 生成器::main(),
                "4" => 原型::main(),
                "5" => 单例::main(),
                _ => 命令行打印("创建型模式"),
            }
        }
        "2" => {
            let 选项二 = 获取选项二("结构型模式");
            match 选项二.as_str() {
                "1" => 适配器::main(),
                "2" => 桥接::main(),
                "3" => 组合::main(),
                "4" => 装饰::main(),
                "5" => 外观::main(),
                "6" => 享元::main(),
                "7" => 代理::main(),
                _ => 命令行打印("结构型模式"),
            }
        }
        "3" => {
            let 选项二 = 获取选项二("行为模式");
            match 选项二.as_str() {
                "1" => 责任链::main(),
                "2" => 命令::main(),
                "3" => 迭代器::main(),
                "4" => 中介者::main(),
                "5" => 备忘录::main(),
                "6" => 观察者::main(),
                "7" => 状态::main(),
                "8" => 策略::main(),
                "9" => 模板方法::main(),
                "10" => 访问者::main(),
                _ => 命令行打印("行为模式"),
            }
        }
        _ => 命令行打印("设计模式"),
    }
}

const 包名: &str = env!("CARGO_PKG_NAME");
const 设计模式: [&str; 3] = ["创建型模式", "结构型模式", "行为模式"];
const 创建型: [&str; 5] = ["工厂方法", "抽象工厂", "生成器", "原型", "单例"];
const 结构型: [&str; 7] = ["适配器", "桥接", "组合", "装饰", "外观", "享元", "代理"];
const 行为: [&str; 10] = [
    "责任链",
    "命令",
    "迭代器",
    "中介者",
    "备忘录",
    "观察者",
    "状态",
    "策略",
    "模板方法",
    "访问者",
];

fn 命令行打印(模式: &str) {
    match 模式 {
        "设计模式" => {
            println!("用法：{}.exe [选项一]", 包名);
            for (序号, &具体模式) in 设计模式.iter().enumerate() {
                println!("{}: {}", 序号 + 1, 具体模式);
            }
        }
        "创建型模式" => {
            println!("用法：{}.exe 1 [选项二]", 包名);
            for (序号, &具体模式) in 创建型.iter().enumerate() {
                println!("{}: {}", 序号 + 1, 具体模式);
            }
        }
        "结构型模式" => {
            println!("用法：{}.exe 2 [选项二]", 包名);
            for (序号, &具体模式) in 结构型.iter().enumerate() {
                println!("{}: {}", 序号 + 1, 具体模式);
            }
        }
        "行为模式" => {
            println!("用法：{}.exe 3 [选项二]", 包名);
            for (序号, &具体模式) in 行为.iter().enumerate() {
                println!("{}: {}", 序号 + 1, 具体模式);
            }
        }
        _ => (),
    }
}

fn 获取选项一() -> String {
    return std::env::args().nth(1).unwrap_or_else(|| {
        打印横幅();
        命令行打印("设计模式");
        std::process::exit(1);
    });
}
fn 获取选项二(模式: &str) -> String {
    return std::env::args().nth(2).unwrap_or_else(|| {
        命令行打印(模式);
        std::process::exit(1);
    });
}

fn 打印横幅() {
    let ascii = r#"
          _
       __| |  _ __
      / _` | | '_ \
     | (_| | | |_) |
      \__,_| | .__/
             |_|
    "#;
    // 打印标题和描述：[打印ASCII艺术文字](https://www.bejson.com/text/ascii_art/)
    // 设置命令行界面的标题和描述
    let cargo_pkg_name = env!("CARGO_PKG_NAME");
    let cargo_pkg_version = env!("CARGO_PKG_VERSION");
    let cargo_pkg_description = env!("CARGO_PKG_DESCRIPTION");
    let title: String = "✨  ".to_string() + cargo_pkg_name + " v" + cargo_pkg_version + " ✨";
    // 设置框的宽度以适合标题和描述
    let width = &title.len().max(cargo_pkg_description.len()) + 4;
    // 创建一条水平线以分隔框
    let horizontal_line = "─".repeat(width - 2);
    // 在框中打印标题和描述
    println!("\n┌{}┐", horizontal_line);
    println!("│{: ^1$}│", title, width - 4);
    println!("├{}┤", horizontal_line);
    println!("│{: ^1$}│", cargo_pkg_description, width - 6);
    println!("└{}┘", horizontal_line);
    println!("{}", ascii);
}
